
// function add(arg1: any, arg2: any): any {
//     return arg1 + arg2
// }
// add(1, '0') //10


// function add(arg1: number, arg2: number): number {
//     return arg1 + arg2
// }
// add(1, 0)
// 泛型


//<T> 表示数字或者字符串


// function add<T>(arg1: T, arg2: T): T {
//     return arg1 + arg2
// }
// add<number>(1, 0)
// add<string>('1', '0')


// 泛型接口
function add<T>(arg1: T, arg2: T): T {
    return arg1 + arg2
}
// let addFunc: <T>(arg1: T, arg2: T) => T
// let addFunc: { <T>(arg1: T, arg2: T): T }
// addFunc = add


// interface GenAdder { <T>(arg1: T, arg2: T): T }
// let addFunc: GenAdder
// addFunc = add
// addFunc<number>(1, 2)
// 



interface GenAdder<T> { (arg1: T, arg2: T): T }
let addFunc: GenAdder<string>
addFunc = add
addFunc('1', '0')

// 泛型类

// class Adder {
//     add: <T>(arg1: T, arg2: T) => T
// }
// const adder = new Adder()
// adder.add = function add<T>(arg1: T, arg2: T) {
//     return arg1 + arg2
// }
function add2(arg1, arg2) {
    return arg1 + arg2
}
class Adder<T> {
    add: (arg1: T, arg2: T) => T
}
const adder = new Adder<number>()
adder.add = add2
adder.add(1, 2)
const stringAdder = new Adder<string>()
stringAdder.add = add2
stringAdder.add('1', '2')


// 泛型约束
interface ILength {
    length: number
}
function getLength<T extends ILength>(arg: T): T {
    console.log(arg.length)
    return arg
}
// getLength<boolean>(false) //报错
getLength<string>('xiaozhang')
// 例子2
function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key]
}

// keyof 
const people = { name: "xiaozhang", age: 16 }
let keys: keyof typeof people

getProperty(people, 'name')
// getProperty(people, 'names')